package com.manager.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;

import com.manager.util.http.HttpParam;

public class HttpHelper {
	public static String JSESSIONID;
	private HttpParam httpParam;
	
	/*
	 * method POST OR GET
	 */
	public HttpHelper(String method){
		httpParam = new HttpParam();
		httpParam.setMethod(method.toUpperCase());
	}
	
	/*
	 * url http://www.xxx.com
	 * content  the data that will send to remote server
	 */
	public String executeMethod(String url, String content){
		String rs = null;
		if(this.httpParam.getMethod().equals("POST")){
			rs = this.executePost(url, content);
		}else{
			rs = this.executeGet(url, content);
		}
		return rs;
	}
	
	/*
	 * 默认是
	 * method:          GET
	 * encode:          UTF-8
	 * contentType:     application/x-www-form-urlencoded
	 * cache:           no-cache
	 * keepSessionId:   false
	 * connectTimeout:  1000 * 10---10秒
	 * readTimeout:     1000 * 60 * 10---10分钟
	 * 
	 * url http://www.xxx.com
	 * param name=xxx&age=xxx
	 */
	public String executeGet(String url, String param){
		URL url2 = null;
		HttpURLConnection httpUrlConnection = null;
		String rs = null;
		
		try {
			url2 = new URL(url + "?" + param);
			//打开与远程服务器的连接，但没有发送任何请求
			httpUrlConnection = (HttpURLConnection) url2.openConnection();
			
			//初始化HttpUrlConnection参数
			initHttpParam(httpUrlConnection);
			
			//每次向远程服务器发送数据时，带上SESSIONID
			this.setSessionId(httpUrlConnection);
			
			//每次得到远程服务器返回信息时，提取SESSIONID
			this.getSessionId(httpUrlConnection);
			
			//读取远程服务器发送回客户端的数据
			rs = this.readDataFromRemoteServer(httpUrlConnection);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			httpUrlConnection.disconnect();
		}
		return rs.toString();
	}
	
	/*
	 * 默认是
	 * method:          POST
	 * encode:          UTF-8
	 * contentType:     application/x-www-form-urlencoded
	 * cache:           no-cache
	 * keepSessionId:   false
	 * connectTimeout:  1000 * 10---10秒
	 * readTimeout:     1000 * 60 * 10---10分钟
	 */
	public String executePost(String url, String content){
		URL url2 = null;
		HttpURLConnection httpUrlConnection = null;
		String rs = null;
		
		try {
			url2 = new URL(url);
			//打开与远程服务器的连接，但没有发送任何请求
			httpUrlConnection = (HttpURLConnection) url2.openConnection();
			
			//初始化HttpUrlConnection参数
			initHttpParam(httpUrlConnection);
			
			//每次向远程服务器发送数据时，带上SESSIONID
			this.setSessionId(httpUrlConnection);
			
			//向远程服务器发送数据
			this.writeDataToRemoteServer(httpUrlConnection, content);
			
			//每次得到远程服务器返回信息时，提取SESSIONID
			this.getSessionId(httpUrlConnection);
			
			//读取远程服务器发送回客户端的数据
			rs = this.readDataFromRemoteServer(httpUrlConnection);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			httpUrlConnection.disconnect();
		}
		return rs.toString();
	}
	
	/*
	 * 初始化请求参数
	 */
	private void initHttpParam(HttpURLConnection huc) throws ProtocolException{
		//以POST方式与远程服务器通信
		huc.setRequestMethod(httpParam.getMethod());
		//允许客户端向远程服务器发送数据
		huc.setDoOutput(true);
		//允许读取从远程服务器发送到客户端的数据
		huc.setDoInput(true);
		//请求不能使用缓存
		huc.setUseCaches(false);
		//指定连接超时时间，10秒
		huc.setConnectTimeout(httpParam.getConnectTimeout());
		//指定读取数据超时时间，10分钟
		huc.setReadTimeout(httpParam.getReadTimeout());
		//指定MIME类型
		huc.setRequestProperty("Content-Type", httpParam.getContentType());
	}
	
	/*
	 * 向远程服务器写数据 
	 */
	private void writeDataToRemoteServer(HttpURLConnection huc, String content){
		BufferedWriter out = null;
		try{
			out = new BufferedWriter(new OutputStreamWriter(huc.getOutputStream(), httpParam.getEncode()));
			out.write(content);
			//关闭输出流
			out.flush();
			out.close();
		}catch(Exception e){
			Log.info("向服务器写数据出错", HttpHelper.class);
			if(out != null){
				try {
					out.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}
	}
	
	/*
	 * 读取远程服务器返回的数据
	 */
	private String readDataFromRemoteServer(HttpURLConnection huc){
		BufferedReader in = null;
		StringBuffer rs = null;
		try{
			in = new BufferedReader(new InputStreamReader(huc.getInputStream(), httpParam.getEncode()));
			rs = new StringBuffer();
			
			int len = 0;
			char[] buffer = new char[1024];
			while ( (len = in.read(buffer)) != -1) {
				rs.append(new String(buffer, 0, len));
			}
			//关闭输入流
			in.close();
		}catch(Exception e){
			Log.info("读取服务器返回数据出错", HttpHelper.class);
			if(in != null){
				try {
					in.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}
		return rs.toString();
	}
	
	/*
	 * 从服务器返回的http头中提取session信息
	 */
	private void setSessionId(HttpURLConnection huc){
		Log.info("set Cookie to server:" + HttpHelper.JSESSIONID);
		if(httpParam.isKeepSessionId()){
			if(HttpHelper.JSESSIONID != null){
				huc.setRequestProperty("Cookie", HttpHelper.JSESSIONID);
			}
		}
	}
	
	/*
	 * 向服务器发送请求时，在http头中设置session
	 */
	private void getSessionId(HttpURLConnection huc){
		if(httpParam.isKeepSessionId()){
			String cookie = huc.getHeaderField("Set-Cookie");
			Log.info("get Set-Cookie1 from server:" + cookie);
			if (cookie != null) {
				String newSessionId = cookie.substring(0,cookie.indexOf(";"));
				if(HttpHelper.JSESSIONID != null && !HttpHelper.JSESSIONID.equals(JSESSIONID)){
					Log.info("session超时");
				}
				HttpHelper.JSESSIONID = newSessionId;
			}
		}
	}
	
	public HttpParam getHttpParam() {
		return httpParam;
	}

	public void setHttpParam(HttpParam httpParam) {
		this.httpParam = httpParam;
	}
	
	public static void main(String[] agrs){
		HttpHelper hp = new HttpHelper("POST");
		hp.getHttpParam().setKeepSessionId(true);
		hp.executeMethod("http://localhost/commonAction!testMethod.ac", "name=aa&password=bb");
		hp.executeMethod("http://localhost/commonAction!testMethod.ac", "name=aa&password=bb");
		hp.executeMethod("http://localhost/commonAction!testMethod.ac", "name=aa&password=bb");
	}
}
